//微信聊天可视化组件
//依赖scrollLoader组件, 依赖指令v-emotion（实现请查看main.js）

//参数：
// width               组件宽度，默认450
// wrapBg              外层父元素背景颜色，默认#efefef
// maxHeight           展示窗口最高高度, 默认900
// contactAvatarUrl    好友头像url
// ownerAvatarUrl      微信主人头像url
// ownerNickname       微信主人昵称
// getUpperData        （必需）当滚动到上方时加载数据的方法，返回值要为Promise对象，resolve的结构同data
// getUnderData        （必需）当滚动到下方时加载数据的方法，返回值同上
// data                （必需）传入初始化数据， 结构如下：
[{
    direction: 2, //为2表示微信主人发出的消息，1表示联系人
    id: 1, //根据这个来排序消息
    type: 1, //1为文本，2为图片
    content: '你好!![呲牙]', //当type为1时这里是文本消息，当type2为2时这里要存放图片地址；后续会支持语音的显示
    ctime: new Date().toLocaleString() //显示当前消息的发送时间
},
{
    direction: 1,
    id: 2,
    type: 1,
    content: '你也好。[害羞]',
    ctime: new Date().toLocaleString()
}]


<style scoped>
.wxchat-container {
  width: 100%;
  height: 100%;
  z-index: 100;
  position: fixed;
  left: 0;
  top: 0;
  overflow: hidden;
}
.shadow {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 100;
  width: 100%;
  height: 100%;
  background: #000;
  opacity: 0.2;
}
.window {
  box-shadow: 1px 1px 20px -5px #000; /*max-width: 450px;*/
  min-width: 300px;
  background: #f5f5f5;
  margin: 0 auto;
  overflow: hidden;
  padding: 0;
  height: 100%;
  position: relative;
  z-index: 101;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
button {
  border: 0;
  background: none;
  border-radius: 0;
  text-align: center;
}
button {
  outline: none;
}
.w100 {
  width: 100%;
}
.mt5 {
  margin-top: 5px;
}
.mt10 {
  margin-top: 10px;
}
.mt20 {
  margin-top: 20px;
}
.mb10 {
  margin-bottom: 10px;
}
.mb20 {
  margin-bottom: 20px;
}
.fs0 {
  font-size: 0;
}
.title {
  background: #fff;
  width: 100%;
  height: 60px;
  font-size: 15px;
  display: flex;
  align-items: center;
  /* margin-top: 5px; */
  justify-content: space-between;
  position: fixed;
  left: 0;
  top: 5px;
}
.title_left {
  display: flex;
  align-items: center;
}
.title > img {
  width: 18px;
  height: 18px;
  margin-right: 20px;
}
.tit_head {
  width: 39px;
  height: 39px;
  border-radius: 50%;
  overflow: hidden;
  margin: 0 7.5px 0 10px;
}
.loading,
.no-more {
  text-align: center;
  color: #b0b0b0;
  line-height: 100px;
}
.no-more {
  line-height: 60px;
}
.pull-right {
  float: right;
}
.link-line {
  text-decoration: underline;
}
.message {
  /*height: 100%;*/
  padding: 10px 15px;
  /*overflow-y: scroll;*/
  background-color: #f5f5f5;
}
.message .read {
  margin-bottom: 15px;
  left: 0;
  position: relative;
  display: block;
}
.message .time {
  margin: 10px 0;
  text-align: center;
}
.message .text {
  display: inline-block;
  position: relative;
  padding: 0 10px;
  max-width: calc(100% - 75px);
  min-height: 35px;
  line-height: 2.1;
  font-size: 15px;
  padding: 6px 10px;
  text-align: left;
  word-break: break-all;
  background-color: #fff;
  color: #000;
  box-shadow: 0px 1px 7px -5px #000;
  border-top-right-radius: 10px;
  border-bottom-left-radius: 18px;
}
.message .avatar {
  float: left;
  margin: 0 10px 0 0;
  border-radius: 3px;
  background: #fff;
  width: 36.5px;
  height: 36.5px;
  border-radius: 50%;
  overflow: hidden;
}
.message .time > span {
  display: inline-block;
  padding: 0 5px;
  font-size: 12px;
  color: #fff;
  border-radius: 2px;
  background-color: #dadada;
}
.message .system > span {
  padding: 4px 9px;
  text-align: left;
}
/* .message .text:before {
        content: " ";
        position: absolute;
        top: 9px;
        right: 100%;
        border: 6px solid transparent;
        border-right-color: #fff;
    } */
.message .self {
  text-align: right;
}
.message .self .avatar {
  float: right;
  margin: 0 0 0 10px;
}
.message .self .text {
  background-color: #e83263;
  color: #fff;
  font-size: 14px;
}

/* .message .self .text:before {
        right: inherit;
        left: 100%;
        border-right-color: transparent;
        border-left-color: #E83263;
    } */
.message .image {
  max-width: 200px;
}
img.static-emotion-gif,
img.static-emotion {
  vertical-align: middle !important;
}

.an-move-left {
  left: 0;
  animation: moveLeft 0.7s ease;
  -webkit-animation: moveLeft 0.7s ease;
}
.an-move-right {
  left: 0;
  animation: moveRight 0.7s ease;
  -webkit-animation: moveRight 0.7s ease;
}
.bgnone {
  background: none;
}
@keyframes moveRight {
  0% {
    left: -20px;
    opacity: 0;
  }
  100% {
    left: 0;
    opacity: 1;
  }
}

@-webkit-keyframes moveRight {
  0% {
    left: -20px;
    opacity: 0;
  }
  100% {
    left: 0px;
    opacity: 1;
  }
}
@keyframes moveLeft {
  0% {
    left: 20px;
    opacity: 0;
  }
  100% {
    left: 0px;
    opacity: 1;
  }
}

@-webkit-keyframes moveLeft {
  0% {
    left: 20px;
    opacity: 0;
  }
  100% {
    left: 0px;
    opacity: 1;
  }
}

@media (max-width: 367px) {
  .fzDInfo {
    width: 82%;
  }
}
.inp_warp {
  display: flex;
  background: #fff;
  height: 50px;
  align-items: center;
  z-index: 999;
  position: fixed;
  width: 100%;
  left: 0;
  bottom: 0;
}
.inp_warp > input {
  width: 252px;
  height: 31px;
  border-radius: 31px;
  border: 1px solid #dcdcdc;
  padding-left: 15px;
  font-size: 12px;
  margin: 0 0 0 15px;
  box-sizing: border-box;
}
.inp_warp > img {
  width: 46px!important;
  height: 46px!important;
  padding: 10px!important;
}
</style>

<template>
  <div class="wxchat-container" :style="{backgroundColor: wrapBg}">
    <div
      class="window"
      id="window-view-container"
      :style="{maxHeight: maxHeight + 'px', width: width +'px'}"
    >
      <!-- data is empty -->
      <!-- <div class="loading" v-if="dataArray && dataArray.length==0">
        <div style="margin-top: 300px;text-align:center; font-size: 16px;">
          <span>未查找到聊天记录</span>
        </div>
      </div> -->

      <!-- loading -->
      <!-- <div class="loading" v-if="dataArray.length==0">
        <div style="margin-top: 300px;">
          <div>加载中...</div>
        </div>
      </div> -->

      <div class="title"  >
        <div class="title_left">
          <img class="tit_head" :src="contactAvatarUrl" @click="findDetails('in')" alt />
          <div>{{contactNickname}}</div>
        </div>
        <img v-if="isFriend==0" src="../assets/ic_addFriend.png" alt @click="addFriend" />
      </div>
      <!-- main -->
      <ScrollLoader
        :minHeight="minHeight"
        @scroll-to-top="refresh"
        class="container-main"
        ref="child"
        :style="{maxHeight: maxHeight-115 + 'px'}"
      >
        <div class="message">

          <ul>
            <div
              v-for="(message, index) in dataArray"
              :key="index"
              :class="message.flow=='out'?'an-move-right':'an-move-left'"
              class="read"
            >
              <p class="time">
                <span >{{message.time|timeFil}}</span>
              </p>
              <!-- <p class="time system" v-if="message.type=='TIMTextElem'">
                <span v-html="message.payload.text"></span>
              </p> -->
              <div :class="'main' + (message.flow=='out'?' self':'')" >
                <img
                  class="avatar"
                  width="45"
                  height="45"
                  @click="findDetails(message.flow)"
                  :src="message.flow=='out'? ownerAvatarUrl: contactAvatarUrl"
                />
                <!-- 文本 -->
                <div class="text"  v-if="message.type=='TIMTextElem'">{{message.payload.text}}</div>

                <!-- 图片 -->
                <div class="text" v-else-if="message.type==2">
                  <img :src="message.payload.text" class="image" alt="聊天图片" />
                </div>

                <!-- 其他 -->
                <div
                  class="text"
                  v-else-if="message.type!=10000"
                  v-text="'[暂未支持的消息类型:'+ message.type +']\n\r' + message.content"
                ></div>
              </div>
            </div>
          </ul>
        </div>
      </ScrollLoader>
      <!-- 输入框 -->
      <div class="inp_warp">
        <input type="text" placeholder="请输入您要发送的信息" @blur="sendBlur"  v-model="sendMes" />
        <img src="../assets/ic_expression.png" style="width:24px;height:24px;" alt />
        <img src="../assets/ic_send.png" alt @click="sendMessage()" />
      </div>
    </div>
  </div>
</template>

<script>
import ScrollLoader from "./scrollLoader.vue";
import { mapActions, mapState } from "vuex";
import * as API from "@/http/common/api";
import tim from "../utils/tim";
import TIM from "tim-js-sdk";
import Vue from "vue";
export default {
  name: "wxChat",

  components: {
    ScrollLoader
  },
  props: {
    contactNickname: {
      type: String,
      default: "Mystic Faces"
    },



    width: {
      type: Number,
      default: 450
    },

    wrapBg: {
      type: String,
      default: "#efefef"
    },


    maxHeight: {
      type: Number,
      default: 700
    },

    contactAvatarUrl: {
      type: String
    },

    ownerAvatarUrl: {
      type: String
    },

    getUpperData: {
      type: Function,
      required: true
    },

    getUnderData: {
      type: Function,
      required: true
    },
    // ---
    objId: {
      type: Number
    },
    userId: {
      type: Number
    },
  },

  data() {
    return {
      isFriend:0,
      isUpperLaoding: false,
      isUnderLaoding: false,
      dataArray:[],  //list对话
      msgs: [], //聊天内容
      isRefreshedAll: false,
      isLoadedAll: false,
      minHeight: 700,
      filterText: [], //过滤词
      userInfo: {},
      pageNumber:null,//页码
      sendMes: "" //输入框
    };
  },

  created() {
  },
  mounted() {
    this.userInfo = JSON.parse(this.$localStorage.get("userInfo"))
    this.filterText = JSON.parse(this.$localStorage.get("filterText"));
    this.minHeight = document.getElementById("window-view-container").offsetHeight;
    // this.maxHeight = document.getElementById("window-view-container").offsetHeight;
    this.initListener(); // 初始化监听器
    this.chatMessageList() //消息列表。
    this._isFriend();   //是否是好友

  },

  methods: {
    getCurrentDate() {
      var timeStr = "-";
      var curDate = new Date();
      var curYear = curDate.getFullYear(); //获取完整的年份(4位,1970-????)
      var curMonth = curDate.getMonth() + 1; //获取当前月份(0-11,0代表1月)
      var curDay = curDate.getDate(); //获取当前日(1-31)
      var curWeekDay = curDate.getDay(); //获取当前星期X(0-6,0代表星期天)
      var curHour = curDate.getHours(); //获取当前小时数(0-23)
      var curMinute = curDate.getMinutes(); // 获取当前分钟数(0-59)
      var curSec = curDate.getSeconds(); //获取当前秒数(0-59)
      var Current =
        curYear +
        timeStr +
        curMonth +
        timeStr +
        curDay +
        " " +
        curHour +
        ":" +
        curMinute +
        ":" +
        curSec;
      console.log(Current); // this.datetime=Current;
      return Current;
    },
    //发送
    sendBlur(){
      window.scroll(0, 0)
      // this.$refs.child.loseInput()
    },
    // sendFocus(){
    //   this.$refs.child.getInput()
    // },
    //是否是好友
    _isFriend(){
      this.$http(API.findFriendMark, {
        type: "GET",
        params: {
          userid: this.userInfo.userId,
          friendid: this.objId,
        }
      }).then(res => {
        if (res.data.code == 0) {
          this.isFriend =res.data.Message
        } else {
          this.$vux.toast.show({
            text: res.data.message,
            type: "text"
          });
        }
      });
    },
    //消息列表。
    chatMessageList(){
      var that =this
      // 打开某个会话时，第一次拉取消息列表
      let promise = tim.getMessageList({conversationID: 'C2C'+that.objId, count: 15});
      promise.then(function(imResponse) {
        that.dataArray =imResponse.data.messageList
        console.log('初次进入消息列表======',imResponse.data.nextReqMessageID)
        that.pageNumber =imResponse.data.nextReqMessageID
        console.log('初次进入消息列表======',that.dataArray)
        if(that.dataArray.length>6){
          that.$refs.child.goDown()
        }
        // const messageList = imResponse.data.messageList; // 消息列表。
        // const nextReqMessageID = imResponse.data.nextReqMessageID; // 用于续拉，分页续拉时需传入该字段。
        // const isCompleted = imResponse.data.isCompleted; // 表示是否已经拉完所有消息。
      });
      // 将某会话下所有未读消息已读上报
      let promisee = tim.setMessageRead({conversationID: 'C2C'+that.objId});
      promisee.then(function(imResponse) {
        // 已读上报成功
        console.log('已读上报成功',imResponse)
      }).catch(function(imError) {
        // 已读上报失败
        console.warn('setMessageRead error:', imError);
      });
    },


    // 初始化监听器
    initListener() {
      // 登录成功后会触发 SDK_READY 事件，该事件触发后，可正常使用 SDK 接口
      tim.on(TIM.EVENT.SDK_READY, this.onReadyStateUpdate, this);
      // SDK NOT READT
      tim.on(TIM.EVENT.SDK_NOT_READY, this.onReadyStateUpdate, this);
      // 被踢出
      tim.on(TIM.EVENT.KICKED_OUT, () => {
        console.log("被踢出，请重新登录。");
      });
      // SDK内部出错
      tim.on(TIM.EVENT.ERROR, this.onError);
      // 收到新消息
      tim.on(TIM.EVENT.MESSAGE_RECEIVED, this.onReceiveMessage);
      // 会话列表更新
      tim.on(TIM.EVENT.CONVERSATION_LIST_UPDATED, event => {
       
      });
      // 群组列表更新
      tim.on(TIM.EVENT.GROUP_LIST_UPDATED, event => {
         
      });
 
    },
    onError({ data }) {
      if (data.message !== "Network Error") {
        console.log("SDK内部错误==", data.message);
      }
    },
    onReadyStateUpdate({ name }) {
      this.tim
        .getMyProfile()
        .then(({ data }) => {
          console.log(data);
        })
        .catch(error => {
          console.log("个人资料err===", error);
        });
    },
    //接受 更新消息
    onReceiveMessage({ data: messageList }) {   
      console.log('messageList==',messageList)
      this.dataArray = [...this.dataArray,...messageList]
      if(that.dataArray.length>6){
        this.$refs.child.goDown()
      }
    },
    //点击发送按钮
    sendMessage() {
      var that =this
      if(!this.sendMes){
        this.$vux.toast.show({ text: "输入内容不能为空", type: "text" });
        return
      }
      let onSdkReady = function(event) {};
      tim.on(TIM.EVENT.SDK_READY, onSdkReady);
      // 1. 创建消息实例，接口返回的实例可以上屏
      var _text = this.$localStorage.get('isFil')=='true'?this.textMessage(this.sendMes) :this.sendMes
      let message = tim.createTextMessage({
        to: that.objId+'',
        conversationType: TIM.TYPES.CONV_C2C,
        payload: {
          text:_text
        }
      });
      // 2. 发送消息
      let promise = tim.sendMessage(message);
      promise
        .then(function(imResponse) {
          // 发送成功
          that.sendMes = ''
          console.log(imResponse.data.message)
          var a = [imResponse.data.message]
          that.dataArray =  [...that.dataArray,...a]
          console.log(that.dataArray )
          if(that.dataArray.length>6){
            that.$refs.child.goDown()
          }
        })
        .catch(function(imError) {
          // 发送失败
          console.log("sendMessage error:", imError);
        });

      // 原逻辑
      if (!this.sendMes)
        return this.$vux.toast.show({ text: "消息为空", type: "text" });
      this.$http(API.add, {
        type: "POST",
        params: {
          userid: this.userInfo.userId,
          friendid: this.objId,
          friendname: this.contactNickname,
          frienduuid: this.contactAvatarUrl,
          chatcontent: this.sendMes,
          lastChatTime: this.getCurrentDate()
        }
      })
        .then(res => {
          if (res.data.code == 0) {
   
          } else {
          }
        })
 
    },
    decodeElement (message) {
      let renderDom = []
      let temp = message.payload.text
      let left = -1
      let right = -1
      while (temp !== '') {
        left = temp.indexOf('[')
        right = temp.indexOf(']')
        switch (left) {
          case 0:
            if (right === -1) {
              renderDom.push({
                name: 'span',
                text: temp
              })
              temp = ''
            } else {
              let _emoji = temp.slice(0, right + 1)
              if (emojiMap[_emoji]) {
                renderDom.push({
                  name: 'img',
                  src: emojiUrl + emojiMap[_emoji]
                })
                temp = temp.substring(right + 1)
              } else {
                renderDom.push({
                  name: 'span',
                  text: '['
                })
                temp = temp.slice(1)
              }
            }
            break
          case -1:
            renderDom.push({
              name: 'span',
              text: temp
            })
            temp = ''
            break
          default:
            renderDom.push({
              name: 'span',
              text: temp.slice(0, left)
            })
            temp = temp.substring(left)
            break
        }
      }
      return renderDom
    },
    //向上拉刷新
    refresh(done) {
      var me = this;
      // if (me.isUpperLaoding) {
      //   return;
      // }
      // if (me.isRefreshedAll) {
      //   done(true);
      //   me.isUpperLaoding = false;
      //   return;
      // }
      // try {
        // 上   查看更多消息
        let promise = tim.getMessageList({conversationID: 'C2C'+me.objId,nextReqMessageID: me.pageNumber, count: 15});
        promise.then(function(imResponse) {
          console.log('上 消息列表=====',imResponse.data.messageList )
          me.pageNumber =imResponse.data.nextReqMessageID
          if(imResponse.data.messageList.length ==0){
            me.isRefreshedAll = true;
            done(true);
          }else{
            console.log('以前',me.dataArray)
            if(imResponse.data.messageList[0].ID==me.dataArray[0].ID){
              me.$vux.toast.show({ text: "没有更多内容了", type: "text" }); 
              return
            }
            let newArr=imResponse.data.messageList     

            me.dataArray = [...newArr,...me.dataArray]
            
            console.log('总list===', me.dataArray)
            done();
          }
        });

      // } catch (error) {
      //   console.error(
      //     'wxChat: props "getUpperData" must return a promise object!'
      //   );
      // }
      me.isUpperLaoding = false;
    },
    //监听 接受消息
    watchMessage(){
      let onMessageReceived = function(event) {
        console.log(event)
        // 收到推送的单聊、群聊、群提示、群系统通知的新消息，可通过遍历 event.data 获取消息列表数据并渲染到页面
        // event.name - TIM.EVENT.MESSAGE_RECEIVED
        // event.data - 存储 Message 对象的数组 - [Message]
      };
      tim.on(TIM.EVENT.MESSAGE_RECEIVED, onMessageReceived);
    },

    //查看对方详情信息
    findDetails(e) {
      if (e == 'in') {
        this.$parent.openDetails();
      }
    },
    //添加朋友
    addFriend(e) {
      this.$parent.openAddFriend();
    },
    // 滚动到底部
    toBottom() {
      this.$nextTick(() => {
        if (null !== this.$refs.read.lastChild) {
          this.$refs.read.lastChild.scrollIntoView();
        }
      });
    },
    hadle_message(data) {
      console.log(data);
      // {type:'welcome',my_id:''}
      if (data.type == "welcome") {
        this.my_id = data.my_id;
      }
      // {type:"member",members:[]}
      if (data.type == "member") {
        this.members = data.members;
        if (this.members[0] == this.my_id && this.members.length > 1) {
          this.chatWith = 1;
        }
      }
      // {type:"chat",from:'',to:'',msg:''}
      if (data.type == "chat") {
        this.msgs.push(data);
        console.log(msgs);
        this.handleMsg();
      }

      // if (data.msg) {
      //   this.chating.push(data)
      // }
    },
    handleMsg() {
      //选择对方
      var other = this.members[this.chatWith];
      console.log(other);
      var tmp = [];
      for (var i in this.msgs) {
        //get聊天记录
        if (this.msgs[i].to == other || this.msgs[i].from == other) {
          tmp.push(this.msgs[i]);
        }
      }
      this.msgBy = JSON.parse(JSON.stringify(tmp)); //聊天记录  写入
      this.toBottom(); //滚到底部
    },
    textMessage(text) {
      //过滤词
      for (var i in this.filterText) {
        if (text.indexOf(this.filterText[i].sensitivityName) > -1) {
          text.replace(this.filterText[i].sensitivityName, "**");
          console.log(text.replace(this.filterText[i].sensitivityName, "**"));
          text = text.replace(this.filterText[i].sensitivityName, "**");
          this.sendMes = text.replace(this.filterText[i].sensitivityName, "**");
        }
      }
      return this.sendMes;
    }
    // ...mapActions({
    //   socket: "SOCKET_INIT"
    //   // send:'SOCKET_SEND',
    // })
  },
  filters: {
    timeFil(val){
      var now = new Date(Number(val+'000'))
      var year=now.getFullYear();  //取得4位数的年份
      var month=now.getMonth()+1;  //取得日期中的月份，其中0表示1月，11表示12月
      var date=now.getDate();      //返回日期月份中的天数（1到31）
      var hour=now.getHours();     //返回日期中的小时数（0到23）
      var minute=now.getMinutes(); //返回日期中的分钟数（0到59）
      var second=now.getSeconds(); //返回日期中的秒数（0到59）
      return year+"-"+month+"-"+date+" "+hour+":"+minute+":"+second; 
    }
  },

};
</script>